﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using InterfazGrafico.LibreriaClases.Clases;
using InterfazGrafico.LibreriaConstantes;
using InterfazGrafico.LibreriaConstantes.Elementos;

namespace InterfazGrafico.LibreriaClases.Propiedades
{
    /// <summary>
    /// Almacena las propiedades de un elemento específico.
    /// </summary>
    public class PEstandarizarDuplicados : Propiedades
    {
        /// <summary>
        /// Entrada de datos.
        /// </summary>
        public string Entrada
        {
            get
            {
                return this.getPropiedadString(CEstandarizarDuplicados.Entrada);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.Entrada, value);
            }
        }

        /// <summary>
        /// Salida de datos.
        /// </summary>
        public string Salida
        {
            get
            {
                return this.getPropiedadString(CEstandarizarDuplicados.Salida);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.Salida, value);
            }
        }

        /// <summary>
        /// Estructura de entrada.
        /// </summary>
        public string EstructuraEntrada
        {
            get
            {
                return this.getPropiedadString(CEstandarizarDuplicados.EstructuraEntrada);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.EstructuraEntrada, value);
            }
        }

        /// <summary>
        /// Estructura de salida.
        /// </summary>
        public string EstructuraSalida
        {
            get
            {
                return this.getPropiedadString(CEstandarizarDuplicados.EstructuraSalida);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.EstructuraSalida, value);
            }
        }

        /// <summary>
        /// Lista campos que conforman la ventana de datos.
        /// </summary>
        public List<string> ListaCamposClave
        {
            get
            {
                return this.getPropiedadListaString(CEstandarizarDuplicados.CamposClave);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.CamposClave, value);
            }
        }

        /// <summary>
        /// Lista de funciones a emplear para realizar la estandarizacion.
        /// </summary>
        public List<string> ListaFuncionesEstandarizacion
        {
            get
            {
                return this.getPropiedadListaString(CEstandarizarDuplicados.FuncionesEstandarizacion);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.FuncionesEstandarizacion, value);
            }
        }

        /// <summary>
        /// Lista de parámetros de las funciones de estandarización.
        /// </summary>
        public List<string> ListaParametrosEstandarizacion
        {
            get
            {
                return this.getPropiedadListaString(CEstandarizarDuplicados.ParametrosFuncionesEstandarizacion);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.ParametrosFuncionesEstandarizacion, value);
            }
        }

        /// <summary>
        /// Lista campos sobre los que aplicar las funciones de estandarización.
        /// </summary>
        public List<string> ListaCamposFuncionesEstandarizacion
        {
            get
            {
                return this.getPropiedadListaString(CEstandarizarDuplicados.CamposProcesarFuncionesEstandarizacion);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.CamposProcesarFuncionesEstandarizacion, value);
            }
        }

        /// <summary>
        /// Lista de campos origen de la estandarización asociados a cada función.
        /// </summary>
        public List<List<string>> ListaCamposOrigenEstandarizacion
        {
            get
            {
                return this.getPropiedadListaListaString(CEstandarizarDuplicados.CamposOrigenEstandarizacion);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.CamposOrigenEstandarizacion, value);
            }
        }

        /// <summary>
        /// Lista de campos destino de la estandarización asociados a cada función.
        /// </summary>
        public List<List<string>> ListaCamposDestinoEstandarizacion
        {
            get
            {
                return this.getPropiedadListaListaString(CEstandarizarDuplicados.CamposDestinoEstandarizacion);
            }
            set
            {
                this.setOrAddPropiedad(CEstandarizarDuplicados.CamposDestinoEstandarizacion, value);
            }
        }

        /// <summary>
        /// Constructor por defecto.
        /// </summary>
        public PEstandarizarDuplicados()
            : base()
        {
        }

        /// <summary>
        /// Obtiene los parámetros a partir del fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        override public void leer(string fichero)
        {
            try
            {
                base.leer(fichero);
                XmlDocument xml = LeerXml.AbrirFicheroParametros(fichero);

                try
                { this.Entrada = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaEntrada); }
                catch (Exception)
                { this.Entrada = string.Empty; };

                try
                { this.Salida = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaSalida); }
                catch (Exception)
                { this.Salida = string.Empty; }

                try
                { this.EstructuraEntrada = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaEstructuraEntrada); }
                catch (Exception)
                { this.EstructuraEntrada = string.Empty; }

                try
                { this.EstructuraSalida = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaEstructuraSalida); }
                catch (Exception)
                { this.EstructuraSalida = string.Empty; }

                // Campos clave
                try
                {
                    int numeroCampos = LeerXml.ObtenerNumeroNodosCampo(xml, CEstandarizarDuplicados.RutaClaves);
                    for (int indiceCampo = 0; indiceCampo < numeroCampos; indiceCampo++)
                    {
                        string campo = string.Empty;
                        try
                        { campo = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaClaves, indiceCampo); }
                        catch (Exception)
                        { continue; }
                        if (!string.Empty.Equals(campo))
                            this.ListaCamposClave.Add(campo);
                    }
                }
                catch (Exception)
                { this.ListaCamposClave = new List<string>(); }

                // Funciones estandarización
                try
                {
                    int numeroFunciones = LeerXml.ObtenerNumeroNodosCampo(xml, CEstandarizarDuplicados.RutaFunciones);
                    for (int indiceFuncion = 0; indiceFuncion < numeroFunciones; indiceFuncion++)
                    {
                        // Función
                        string funcion = string.Empty;
                        try
                        { funcion = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionFuncion); }
                        catch (Exception)
                        { funcion = string.Empty; }
                        if (!string.Empty.Equals(funcion) && new CListasFunciones().ListaFuncionesEstandarizacion.Contains(funcion))
                        {
                            this.ListaFuncionesEstandarizacion.Add(funcion);
                            // Parámetros
                            string parametros = string.Empty;
                            try
                            { parametros = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionParametros); }
                            catch (Exception)
                            { parametros = string.Empty; }
                            this.ListaParametrosEstandarizacion.Add(parametros);

                            // Campo a procesar
                            string campoProcesar = string.Empty;
                            try
                            { campoProcesar = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCampoFuncion); }
                            catch (Exception)
                            { campoProcesar = string.Empty; }
                            this.ListaCamposFuncionesEstandarizacion.Add(campoProcesar);

                            // Campos origen y destino
                            List<string> camposOrigen = new List<string>();
                            List<string> camposDestino = new List<string>();
                            try
                            {
                                int numeroCamposEstandarizar = LeerXml.ObtenerNumeroNodosCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizar);
                                for (int indiceCampo = 0; indiceCampo < numeroCamposEstandarizar; indiceCampo++)
                                {
                                    // Campo origen
                                    string campoOrigen = string.Empty;
                                    try
                                    { campoOrigen = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizar, indiceCampo, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizarCamposCampoOrigen); }
                                    catch (Exception)
                                    { campoOrigen = string.Empty; }

                                    // Campo destino
                                    string campoDestino = string.Empty;
                                    try
                                    { campoDestino = LeerXml.ObtenerValorCampo(xml, CEstandarizarDuplicados.RutaFunciones, indiceFuncion, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizar, indiceCampo, Constantes.NodoXMLActual + CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizarCamposCampoDestino); }
                                    catch (Exception)
                                    { campoDestino = string.Empty; }

                                    if (!string.Empty.Equals(campoOrigen) || !string.Empty.Equals(campoDestino))
                                    {
                                        camposOrigen.Add(campoOrigen);
                                        camposDestino.Add(campoDestino);
                                    }
                                }
                            }
                            catch (Exception)
                            {
                                camposOrigen = new List<string>();
                                camposDestino = new List<string>();
                            }
                            this.ListaCamposOrigenEstandarizacion.Add(camposOrigen);
                            this.ListaCamposDestinoEstandarizacion.Add(camposDestino);
                        }
                    }
                }
                catch(Exception)
                {
                    this.ListaFuncionesEstandarizacion = new List<string>();
                    this.ListaParametrosEstandarizacion = new List<string>();
                    this.ListaCamposFuncionesEstandarizacion = new List<string>();
                    this.ListaCamposOrigenEstandarizacion = new List<List<string>>();
                    this.ListaCamposDestinoEstandarizacion = new List<List<string>>();
                }
            }
            catch (Exception ex)
            {
                throw new ApplicationException(Constantes.ERROR_LECTURA_FICHERO_CONFIGURACION, ex);
            }
        }

        /// <summary>
        /// Escribe los parámetros al fichero XML indicado.
        /// </summary>
        /// <param name="fichero">Fichero de configuración XML</param>
        public override void escribir(string fichero)
        {
            try
            {
                base.escribir(fichero);
                XmlWriter xml = EscribirXml.AbrirFicheroParametros(fichero);
                EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoRaiz);
                EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoEntrada, Entrada);
                EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoSalida, Salida);
                EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoEstructuraEntrada, EstructuraEntrada);
                EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoEstructuraSalida, EstructuraSalida);

                // Configuración
                EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoConfiguracion);

                // Campos clave
                EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoClaves);
                foreach (string campo in ListaCamposClave)
                    EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoClavesClave, campo);
                EscribirXml.FinElemento(xml);

                // Funciones
                EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoFunciones);
                for (int indiceFuncion = 0; indiceFuncion < ListaFuncionesEstandarizacion.Count; indiceFuncion++)
                {
                    EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoFuncionesFuncion);
                    // Funcion
                    EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoFuncionesFuncionFuncion, ListaFuncionesEstandarizacion[indiceFuncion]);
                    // Parametros
                    EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoFuncionesFuncionParametros, ListaParametrosEstandarizacion[indiceFuncion]);
                    // Campo a procesar
                    EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoFuncionesFuncionCampoFuncion, ListaCamposFuncionesEstandarizacion[indiceFuncion]);
                    // Campos a estandarizar
                    EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizar);
                    for (int indiceCampo = 0; indiceCampo < ListaCamposOrigenEstandarizacion[indiceFuncion].Count; indiceCampo++)
                    {
                        EscribirXml.InicioElemento(xml, CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizarCampos);
                        // Campo origen
                        EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizarCamposCampoOrigen, ListaCamposOrigenEstandarizacion[indiceFuncion][indiceCampo]);
                        // Campo destino
                        EscribirXml.EscribeNodo(xml, CEstandarizarDuplicados.NodoFuncionesFuncionCamposEstandarizarCamposCampoDestino, ListaCamposDestinoEstandarizacion[indiceFuncion][indiceCampo]);
                        EscribirXml.FinElemento(xml);
                    }
                    EscribirXml.FinElemento(xml);
                    EscribirXml.FinElemento(xml);
                }
                EscribirXml.FinElemento(xml);
                
                EscribirXml.FinElemento(xml);
                EscribirXml.FinElemento(xml);
                EscribirXml.Flush(xml);
                EscribirXml.Close(xml);
            }
            catch (Exception ex)
            {
                throw new ApplicationException(Constantes.ERROR_ESCRITURA_FICHERO_CONFIGURACION, ex);
            }
        }
    }
}
 